package com.prim.thread;

/**
 * 线程的几种状态
 * NEW : 尚未启动的线程的线程状态
 * Runnable:可运行的线程的线程状态，等待CPU调度
 * Blocked：线程阻塞等待监视器锁定的线程状态 处于synchronized同步代码块或方法中被阻塞
 * Waiting:线程等待的线程状态。Object.wait Thread.join LockSupport.park
 * TIMED_WAITING:指具有指定等待时间的等待线程的线程状态
 * Thread.sleep
 * Object.wait
 * Thread.join
 * LockSupport.parkNanos
 * LockSupport.parkUntil
 * TERMINATED：终止线程的线程状态。线程正常执行完毕或出现异常
 *
 * @author prim
 */
public class ThreadState {
    private Thread thread1;

    public static void main(String[] args) throws Exception {
//        test1();
//        test2();
        test3();
    }

    public static void test1() throws InterruptedException {
        System.out.println("### 第一种线程状态：新建 -> 运行 -> 终止(sleep方式)");
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("子线程发来贺电.......");
            }
        });
        System.out.println("1 --> 调用start方法之前的状态:" + thread.getState());
        Thread.sleep(2000);
        thread.start();
        System.out.println("2 --> 调用start方法之后的状态:" + thread.getState());
        Thread.sleep(4000);//等待线程执行结束 在看状态
        System.out.println("3 --> 2S之后的，状态:" + thread.getState());
//        thread.start();//注意当线程终止后 在调用会抛出异常
    }

    public static void test2() throws InterruptedException {
        System.out.println("### 第二种线程状态:新建 -> 运行 -> 等待 -> 运行 -> 终止(sleep方式)");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000L);
                    System.out.println("3 --> sleep结束后状态：" + Thread.currentThread().getState());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        System.out.println("0 --> 调用start之前状态:" + thread2.getState().toString());
        thread2.start();
        System.out.println("1 --> 调用start之后状态:" + thread2.getState().toString());
        Thread.sleep(2000L);
        System.out.println("2 --> 等待2000ms,状态:" + thread2.getState().toString());
        Thread.sleep(6000L);
        System.out.println("4 --> 等待线程运行完毕后状态:" + thread2.getState().toString());
    }

    public static void test3() throws InterruptedException {
        System.out.println("### 第三种线程状态:NEW -> RUNNABLE ->BLOCKED -> RUNNABLE -> TERMINATED");
        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("1--> 抢锁之前的状态：" + Thread.currentThread().getState().toString());
                synchronized (ThreadState.class) {
                    System.out.println("5 --> thread3拿到锁，继续执行。状态:" + Thread.currentThread().getState());
                }
            }
        });
        synchronized (ThreadState.class) {
            System.out.println("0 --> 主动拿到锁，启动thread3：" + thread3.getState().toString());
            thread3.start();
            System.out.println("2 --> 调用start方法后状态:" + thread3.getState().toString());
            Thread.sleep(5000);
            System.out.println("3 --> sleep 5000 之后的状态:" + thread3.getState().toString());
            Thread.sleep(2400L);
        }
        System.out.println("4 --> 主线程释放锁");
    }
}
